Add structured logging, MCP request logging, and an OpenTelemetry pipeline across server apps#1328
Open
FelineStateMachine wants to merge 3 commits into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Outside of
apps/cloud, the server apps have no configured logger (Effect'sdefault pretty printer), no log or metric export, and no tracer, so the
roughly 145 existing
Effect.withSpancall sites in core packages exportnothing. MCP protocol traffic is only visible through the
EXECUTOR_MCP_DEBUGconsole hook. This makes self-hosted and local deployments harder to operate and
debug.
Closes #1231.
Changes
packages/core/observabilitypackage exportingobservabilityLayer({ serviceName, endpoint, headers, logLevel }): a structured JSON console logger plus OTLP/HTTP export of traces, logs, and metrics. Built oneffect/unstable/observability(fetch-based), so the same layer runs on Bun and Cloudflare workerd. No new dependencies; export is disabled when no endpoint is configured.local,host-selfhost,host-cloudflare,cloud) boot the layer from their own environment source. Cloud keeps its existing trace pipeline and error-capture correlation and gains only logs and metrics.mcp.*log events across the MCP host: tool start/end with outcome and duration, internal errors with a correlation id, session lifecycle, auth outcomes, and elicitation at debug level. Two metrics,mcp.tool.callsandmcp.tool.duration_ms, tagged by tool and outcome. Code payloads are not logged, onlymcp.execute.code_length.SpanKind.CONSUMER, so span classifiers treat each call as a unit of work instead of discarding a root internal span (the stdio transport case).trace_id/span_idfor correlation with exported traces.HttpMiddleware.logger) is replaced with a composed request summary (GET /api/things 200 in 12ms) via a sharedhttpAccessLoggermiddleware, keeping the samehttp.*annotations and addinghttp.duration_ms.AGENTS.md, configuration inRUNNING.md.EXECUTOR_MCP_DEBUGis unchanged.Configuration
OTEL_EXPORTER_OTLP_ENDPOINT/v1/{traces,logs,metrics}appended. Unset disables export.OTEL_EXPORTER_OTLP_HEADERSkey=value,key2=value2format.LOG_LEVELinfoOn the Workers apps these are bindings rather than process env.
Testing and verification
format:check,lint,typecheck, andtestpass.disabled-when-unconfigured behavior, OTLP layer teardown; MCP host tests
assert
mcp.tool.start/mcp.tool.endfire with outcome, duration, andexecution id, and that defects produce the correlation-id error log.
/v1/traces, trace-correlated log records on/v1/logs, both metric serieson
/v1/metrics.apps/host-selfhostand
apps/local). Screenshots below. With the endpoint unset, there is nonetwork activity and existing e2e tests (including the cloud
error-correlation contract test) pass unchanged.
MCP tool call classified as a task via
SpanKind.CONSUMER, with toolattributes and child spans:
Endpoint grouped by parametrized route with database child spans:
Disclosure
This change was developed with an LLM coding assistant (Claude).